package com.whsxt.service.impl;

import cn.hutool.core.date.DateTime;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.whsxt.common.CodeMsg;
import com.whsxt.common.Constants;
import com.whsxt.domain.Car;
import com.whsxt.domain.Customer;
import com.whsxt.domain.Rent;
import com.whsxt.dto.CarDto;
import com.whsxt.exception.BusinessException;
import com.whsxt.mapper.CarMapper;
import com.whsxt.mapper.CustomerMapper;
import com.whsxt.mapper.RentMapper;
import com.whsxt.service.CarService;
import com.whsxt.utils.CurrentLoginUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.Date;
import java.util.List;

@Service
public class CarServiceImpl implements CarService {

    @Autowired
    private CarMapper carMapper;

    @Autowired
    private CustomerMapper customerMapper;

    @Autowired
    private RentMapper rentMapper;

    /**
     * 查询分页的车辆数据
     * @param carDto
     * @return
     */
    @Override
    public PageInfo<Car> findByPage(CarDto carDto) {
        // 开启分页
        Page<Object> objects = PageHelper.startPage(carDto.getPage(), carDto.getLimit());
        // 查询数据
        List<Car> carList = carMapper.selectPage(carDto);
        PageInfo<Car> pageInfo = new PageInfo<>(carList);
        pageInfo.setTotal(objects.getTotal());
        return pageInfo;
    }

    /**
     * 新增数据
     * @param carDto
     * @return
     */
    @Override
    public boolean save(CarDto carDto) {
        // 属性的校验
        validate(carDto);
        // 属性的拷贝
        Car car = new Car();
        BeanUtils.copyProperties(carDto, car);
        // 默认值的填充
        car.setIsRent(Constants.DEFAULT_CAR_RENT_STATUS);
        car.setCreateTime(new Date());
        car.setVersion(Constants.DEFAULT_CAR_VERSION);
        // 新增数据
        int row = carMapper.insert(car);
        return row > 0;
    }

    /**
     * 通过id集合删除数据
     * @param ids
     * @return
     */
    @Override
    public boolean batchRemove(List<Integer> ids) {
        return carMapper.batchDelete(ids) > 0;
    }

    /**
     * 修改一辆车的数据
     * @param carDto
     * @return
     */
    @Override
    public boolean update(CarDto carDto) {
        // 先查询数据库要存在需要更新的数据
        Car car =  carMapper.selectByPrimaryKey(carDto.getId());
        if(car == null){
            throw new IllegalArgumentException("要修改的数据不存在");
        }

        // 校验数据
        if(!carDto.getNum().equals(car.getNum())){
            throw new IllegalArgumentException("修改车辆的车牌号数据不一致");
        }

        // 数据的复制
        Car update = new Car();
        BeanUtils.copyProperties(carDto, update);

        // 修改数据
        return carMapper.updateByPrimaryKey(update) > 0;
    }

    /**
     * 车辆出租业务
     * @param carId 出租车辆的id
     * @param customerId 客户的id
     * @param beginTime  租车开始时间
     * @param endTime    租车结束时间
     * @return
     */
    @Override
    @Transactional
    public boolean rent(Integer carId, Integer customerId, String beginTime, String endTime) {
        // 先校验数据
        Car car = carMapper.selectByPrimaryKey(carId);
        // 校验车辆是否存在
        if(car == null){
            throw new BusinessException(CodeMsg.CAR_NOT_FOUND);
        }
        if(car.getIsRent().equals(Constants.CAR_RENTED_STATUS)){
            throw new BusinessException(CodeMsg.CAR_RENTED);
        }
        Customer customer = customerMapper.selectByPrimaryKey(customerId);
        if(customer == null){
            throw new BusinessException(CodeMsg.CUSTOMER_NOT_FOUND);
        }

        // 考虑对哪些表产生影响 bus_car 状态修改    bus_rent 插入数据
        // 产生记录时，应先插入数据记录然后再修改车辆的状态
        // 1.插入数据
        Rent rent = new Rent();

        // 利用 BeanUtil来获取复制数据
        BeanUtils.copyProperties(car,rent);
        BeanUtils.copyProperties(customer,rent);
        rent.setId(null);
        rent.setBeginTime(beginTime);
        rent.setEndTime(endTime);
        rent.setFlag(Constants.CAR_NO_RETURN);
        rent.setUserId(CurrentLoginUtil.getLoginUserId());
        rent.setCreateTime(new Date());
        rent.setUpdateTime(new Date());

        int rows = rentMapper.insert(rent);

        // 当前新增记录成功才执行修改操作
        int updateRows = 0;
        if(rows > 0){
            // 出租车辆会有并发量，所以使用乐观锁实现
            Car update = new Car();
            update.setId(car.getId());
            update.setIsRent(Constants.CAR_RENTED_STATUS);
            update.setVersion(car.getVersion());
            // 修改表
            updateRows = carMapper.updateCarRentStaus(update);
        }


        return updateRows > 0;
    }

    /**
     * 对数据的属性的校验
     * @param carDto
     */
    private void validate(CarDto carDto) {
        if(!StringUtils.hasText(carDto.getNum())){
            throw new IllegalArgumentException("车牌不能为空");
        }

        if(carDto.getPrice() == null || carDto.getPrice() < 0){
            throw new IllegalArgumentException("车俩价格不合法");
        }

        if(carDto.getRentPrice() == null || carDto.getRentPrice() < 0){
            throw new IllegalArgumentException("租车的价格不合法");
        }

        int count = carMapper.selectCountByNum(carDto.getNum());

        if(count > 0){
            throw new BusinessException(CodeMsg.CAR_NUMBER_FOUND);
        }
    }
}
